/**
    Copyright (c) 2010 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "DataBufferDX11.h"
#include "DXHelper.h"

/**
*/
DataBufferDX11::DataBufferDX11() : m_pBufferGPU( NULL ), m_pBufferCPU( NULL ), m_pSRVGPU( NULL ), m_pSRVCPU( NULL )
{
}

/**
*/
DataBufferDX11::~DataBufferDX11()
{
}

/**
    @param pd3dDevice    [in]            D3D Device
    @param nWidth        [in]            DataBuffer width
    @param nHeight        [in]            DataBuffer height
*/
HRESULT DataBufferDX11::Create( ID3D11Device* pd3dDevice, int nWidth, int nHeight )
{
    DataBuffer::Create( nWidth, nHeight );

    HRESULT hr = S_OK; 

    // create structured buffer for the cpu
    V_RETURN( CreateStructuredBufferForCPU( pd3dDevice, sizeof(BufType), static_cast< UINT >( m_data.size() ), &m_data[ 0 ], &m_pBufferCPU ) );
    // create structured buffer for the gpu
    V_RETURN( CreateStructuredBufferOnGPU( pd3dDevice, sizeof(BufType), static_cast< UINT >( m_data.size() ), &m_data[ 0 ], &m_pBufferGPU ) );

    // create shader resource view for cpu
    V_RETURN( CreateBufferSRV( pd3dDevice, m_pBufferCPU, &m_pSRVCPU ) );
    // create shader resource view for gpu
    V_RETURN( CreateBufferSRV( pd3dDevice, m_pBufferGPU, &m_pSRVGPU ) );
    
    return hr;
}

/**
*/
HRESULT DataBufferDX11::OnResizedSwapChain( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc )
{
    HRESULT hr = S_OK;

    Destroy();
    V_RETURN( Create( pd3dDevice, pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height ) );

    return hr;
}

/**
    @param pd3dDevice                [in]            D3D Device
    @param pd3dImmediateContext        [in]            D3D Device Immediate Context
*/
void DataBufferDX11::UpdateBuffer( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext )
{
    D3D11_MAPPED_SUBRESOURCE MappedResource;
    pd3dImmediateContext->Map( m_pBufferCPU, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
    memcpy( MappedResource.pData, &m_data[ 0 ], m_data.size()*sizeof(BufType) );
    pd3dImmediateContext->Unmap( m_pBufferCPU, 0 );
}

/**
*/
void DataBufferDX11::Destroy()
{
    SAFE_RELEASE( m_pBufferGPU );
    SAFE_RELEASE( m_pBufferCPU );
    SAFE_RELEASE( m_pSRVGPU );
    SAFE_RELEASE( m_pSRVCPU );
}

